package com.zx.account.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.zx.account.entity.Month;
import com.zx.account.entity.User;
import com.zx.account.model.BurnChartDataDto;
import com.zx.account.model.BurnChartDto;
import com.zx.account.model.StatisticsDto;
import com.zx.account.service.AccountService;
import com.zx.account.service.MonthService;
import com.zx.util.Constants;
import com.zx.util.SessionDataUtil;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;


/**
 * @version v1.0
 * @Project: managing-self
 * @Title: AccountBurnChartController
 * @Description: 预算燃尽图报表
 * @author: zhangxue
 * @date: 2019年10月5日下午8:00:05
 * @company: 未知
 * @Copyright: Copyright (c) 2015
 */
@Controller
@RequestMapping("/account")
public class AccountBurnChartController {

    @Autowired
    private MonthService ms;

    @Autowired
    private AccountService accountService;

    /**
     * @param data
     * @param template
     * @return
     * @Title: 对数据进行填充
     * @date: 2018年6月30日下午4:18:49
     */
    private static List<BurnChartDto> fillData(List<BurnChartDto> data, int year, int month) {
        List<BurnChartDto> templates = getTemplate(year, month);
        for (BurnChartDto tp : templates) {
            String time = tp.getTime();
            for (BurnChartDto dto : data) {
                if (time.equals(dto.getTime())) {
                    tp.setAccount(dto.getAccount());
                    break;
                }
            }
        }
        return templates;
    }

    /**
     * 获得报表模板--每天一条数据
     *
     * @param year
     * @param month
     * @return
     * @author: xue.zhang
     * @date 2018年6月28日上午11:39:24
     */
    private static List<BurnChartDto> getTemplate(int year, int month) {
        Calendar cal = Calendar.getInstance();
        cal.set(year, month - 1, 1);
        Date beginTime = cal.getTime();

        cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
        Date lastTime = cal.getTime();

        long oneDay = 1000L * 60 * 60 * 24;
        List<BurnChartDto> data = new ArrayList<>();
        while (beginTime.getTime() <= lastTime.getTime()) {
            String time = DateUtil.format(beginTime, Constants.DATE_FORMAT_4);
            cal.setTime(beginTime);
            Integer week = cal.get(Calendar.DAY_OF_WEEK);
            week = week == 1 ? 7 : week - 1;
            data.add(new BurnChartDto(time, 0, week.toString()));
            beginTime.setTime(beginTime.getTime() + oneDay);
        }
        return data;
    }

    /**
     * @param year
     * @param month
     * @return
     * @Title: 获得餐饮类的数据模板
     * @date: 2018年6月30日下午4:15:18
     */
    private static List<BurnChartDto> getCateringTemplate(String week1, String week2, int year, int month) {
        Double w1 = 0D;
        Double w2 = 0D;
        if (week1 != null && !"".equals(week1) && week2 != null && !"".equals(week2)) {
            w1 = Double.parseDouble(week1);
            w2 = Double.parseDouble(week2);
        }
        List<BurnChartDto> template = getTemplate(year, month);
        for (BurnChartDto dto : template) {
            String week = dto.getWeek();
            if ("6".equals(week) || "7".equals(week)) {
                dto.setAccount(w2);
            } else {
                dto.setAccount(w1);
            }
        }
        return template;
    }

    private static List<Double> getBurn(double budgetCount, List<BurnChartDto> data) {
        List<Double> res = new ArrayList<>();
        for (BurnChartDto dto : data) {
            budgetCount -= dto.getAccount();
            res.add(NumberUtil.round(budgetCount, 2).doubleValue());
        }
        return res;
    }

    /**
     * @return
     * @Title: 统计数据的合计与均值
     * @date: 2018年6月30日下午4:16:05
     */
    private static StatisticsDto statistics(List<BurnChartDto> data) {
        Double sum = 0d;
        for (BurnChartDto dto : data) {
            sum += dto.getAccount();
        }
        sum = NumberUtil.round(sum, 2).doubleValue();
        double avg = NumberUtil.round(sum / data.size(), 2).doubleValue();

        StatisticsDto sta = new StatisticsDto(avg, sum);
        return sta;
    }

    @RequestMapping(value = "/burnView", method = RequestMethod.GET)
    public ModelAndView index(ModelAndView m) {
        User user = SessionDataUtil.getUserInfo();
        // 查询所有的年和月
        List<Month> all = ms.getByUserId(user.getId());
        m.addObject("yearMonth", all);
        m.setViewName("account/burnView");
        return m;
    }

    @RequestMapping("/burn")
    @ResponseBody
    public BurnChartDataDto get(String yearStr, String monthStr, String type, String week1, String week2) {
        User user = SessionDataUtil.getUserInfo();
        int year = Integer.parseInt(yearStr);
        int month = Integer.parseInt(monthStr);
        int[] types = new int[0];
        List<BurnChartDto> template = new ArrayList<>();

        if ("1".equals(type)) {//餐饮类
            types = new int[]{1, 2, 3, 6};
            template = getCateringTemplate(week1, week2, year, month);
        } else {
            template = new ArrayList<>();
        }
        // 查询数据
        List<BurnChartDto> data = accountService.getBurnDataByType(
                types, year, month, user.getId());
        // 填充数据
        data = fillData(data, year, month);
        // 实际消费统计
        StatisticsDto use = statistics(data);
        // 预算消费统计
        StatisticsDto budget = statistics(template);
        // 使用百分比
        long round = Math.round((use.getSum() / budget.getSum() * 100));
        List<Double> useBurn = getBurn(budget.getSum(), data);
        List<Double> budgetBurn = getBurn(budget.getSum(), template);

        // 封装成统计数据
        BurnChartDataDto res = new BurnChartDataDto(yearStr + "-" + monthStr, data, template,
                budget.getAvg(), budget.getSum(),
                use.getAvg(), use.getSum(),
                template.size(), (double) round);

        res.setUseBurn(useBurn);
        res.setBudgetBurn(budgetBurn);

        return res;
    }
}
